home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_069 / make / input.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  7KB  |  323 lines

  1. /*
  2.  *    Parse a makefile
  3.  */
  4.  
  5.  
  6. #include <stdio.h>
  7. #include    <ctype.h>
  8. #include "h.h"
  9.  
  10.  
  11. struct name     namehead;
  12. struct name    *firstname;
  13.  
  14. char            str1[LZ];    /* General store  */
  15. char            str2[LZ];
  16.  
  17.  
  18. /*
  19.  *    Intern a name.  Return a pointer to the name struct
  20.  */
  21. struct name    *
  22. newname(name)
  23.     char           *name;
  24. {
  25.     register struct name *rp;
  26.     register struct name *rrp;
  27.     register char  *cp;
  28.  
  29.  
  30.     for
  31.     (
  32.      rp = namehead.n_next, rrp = &namehead;
  33.      rp;
  34.      rp = rp->n_next, rrp = rrp->n_next
  35.     )
  36.     if (strcmp(name, rp->n_name) == 0)
  37.         return rp;
  38.  
  39.     if ((rp = (struct name *) malloc(sizeof(struct name)))
  40.     == (struct name *) 0)
  41.     fatal("No memory for name");
  42.     rrp->n_next = rp;
  43.     rp->n_next = (struct name *) 0;
  44.     if ((cp = malloc((unsigned) strlen(name) + 1)) == (char *) 0)
  45.     fatal("No memory for name");
  46.     strcpy(cp, name);
  47.     rp->n_name = cp;
  48.     rp->n_line = (struct line *) 0;
  49.     rp->n_time = (time_t) 0;
  50.     rp->n_flag = 0;
  51.  
  52.     return rp;
  53. }
  54.  
  55.  
  56. /*
  57.  *    Add a dependant to the end of the supplied list of dependants.
  58.  *    Return the new head pointer for that list.
  59.  */
  60. struct depend  *
  61. newdep(np, dp)
  62.     struct name    *np;
  63.     struct depend  *dp;
  64. {
  65.     register struct depend *rp;
  66.     register struct depend *rrp;
  67.  
  68.  
  69.     if ((rp = (struct depend *) malloc(sizeof(struct depend)))
  70.     == (struct depend *) 0)
  71.     fatal("No memory for dependant");
  72.     rp->d_next = (struct depend *) 0;
  73.     rp->d_name = np;
  74.  
  75.     if (dp == (struct depend *) 0)
  76.     return rp;
  77.  
  78.     for (rrp = dp; rrp->d_next; rrp = rrp->d_next);
  79.  
  80.     rrp->d_next = rp;
  81.  
  82.     return dp;
  83. }
  84.  
  85.  
  86. /*
  87.  *    Add a command to the end of the supplied list of commands.
  88.  *    Return the new head pointer for that list.
  89.  */
  90. struct cmd     *
  91. newcmd(str, cp)
  92.     char           *str;
  93.     struct cmd     *cp;
  94. {
  95.     register struct cmd *rp;
  96.     register struct cmd *rrp;
  97.     register char  *rcp;
  98.  
  99.  
  100.     if (rcp = rindex(str, '\n'))
  101.     *rcp = '\0';        /* Loose newline  */
  102.  
  103.     while (isspace(*str))
  104.     str++;
  105.  
  106.     if (*str == '\0')        /* If nothing left, the exit  */
  107.     return (struct cmd *) 0;
  108.  
  109.     if ((rp = (struct cmd *) malloc(sizeof(struct cmd)))
  110.     == (struct cmd *) 0)
  111.     fatal("No memory for command");
  112.     rp->c_next = (struct cmd *) 0;
  113.     if ((rcp = malloc((unsigned) strlen(str) + 1)) == (char *) 0)
  114.     fatal("No memory for command");
  115.     strcpy(rcp, str);
  116.     rp->c_cmd = rcp;
  117.  
  118.     if (cp == (struct cmd *) 0)
  119.     return rp;
  120.  
  121.     for (rrp = cp; rrp->c_next; rrp = rrp->c_next);
  122.  
  123.     rrp->c_next = rp;
  124.  
  125.     return cp;
  126. }
  127.  
  128.  
  129. /*
  130.  *    Add a new 'line' of stuff to a target.  This check to see
  131.  *    if commands already exist for the target.  If flag is set,
  132.  *    the line is a double colon target.
  133.  *
  134.  *    Kludges:
  135.  *    i)  If the new name begins with a '.', and there are no dependents,
  136.  *        then the target must cease to be a target.  This is for .SUFFIXES.
  137.  *    ii) If the new name begins with a '.', with no dependents and has
  138.  *        commands, then replace the current commands.  This is for
  139.  *        redefining commands for a default rule.
  140.  *    Neither of these free the space used by dependents or commands,
  141.  *    since they could be used by another target.
  142.  */
  143. void
  144. newline(np, dp, cp, flag)
  145.     struct name    *np;
  146.     struct depend  *dp;
  147.     struct cmd     *cp;
  148.     bool        flag;
  149. {
  150.     bool            hascmds = FALSE;    /* Target has commands  */
  151.     register struct line *rp;
  152.     register struct line *rrp;
  153.  
  154.  
  155.     /* Handle the .SUFFIXES case */
  156.     if (np->n_name[0] == '.' && !dp && !cp) {
  157.     for (rp = np->n_line; rp; rp = rrp) {
  158.         rrp = rp->l_next;
  159.         free((char *) rp);
  160.     }
  161.     np->n_line = (struct line *) 0;
  162.     np->n_flag &= ~N_TARG;
  163.     return;
  164.     }
  165.     /* This loop must happen since rrp is used later. */
  166.     for
  167.     (
  168.      rp = np->n_line, rrp = (struct line *) 0;
  169.      rp;
  170.      rrp = rp, rp = rp->l_next
  171.     )
  172.     if (rp->l_cmd)
  173.         hascmds = TRUE;
  174.  
  175.     if (hascmds && cp && !(np->n_flag & N_DOUBLE))
  176.     /* Handle the implicit rules redefinition case */
  177.     if (np->n_name[0] == '.' && dp == (struct depend *) 0) {
  178.         np->n_line->l_cmd = cp;
  179.         return;
  180.     } else
  181.         error("Commands defined twice for target %s", np->n_name);
  182.     if (np->n_flag & N_TARG)
  183.     if (!(np->n_flag & N_DOUBLE) != !flag)    /* like xor */
  184.         error("Inconsistent rules for target %s", np->n_name);
  185.  
  186.     if ((rp = (struct line *) malloc(sizeof(struct line)))
  187.     == (struct line *) 0)
  188.     fatal("No memory for line");
  189.     rp->l_next = (struct line *) 0;
  190.     rp->l_dep = dp;
  191.     rp->l_cmd = cp;
  192.  
  193.     if (rrp)
  194.     rrp->l_next = rp;
  195.     else
  196.     np->n_line = rp;
  197.  
  198.     np->n_flag |= N_TARG;
  199.     if (flag)
  200.     np->n_flag |= N_DOUBLE;
  201. }
  202.  
  203.  
  204. /*
  205.  *    Parse input from the makefile, and construct a tree structure
  206.  *    of it.
  207.  */
  208. void
  209. input(fd)
  210.     FILE           *fd;
  211. {
  212.     char           *p;        /* General  */
  213.     char           *q;
  214.     struct name    *np;
  215.     struct depend  *dp;
  216.     struct cmd     *cp;
  217.     bool            dbl, getline();
  218.  
  219.  
  220.     if (getline(str1, fd))    /* Read the first line  */
  221.     return;
  222.  
  223.     for (;;) {
  224. #ifdef os9
  225.     if (*str1 == ' ')    /* Rules without targets  */
  226. # else
  227.         if (*str1 == '\t')    /* Rules without targets  */
  228. # endif
  229.         error("Rules not allowed here");
  230.  
  231.     p = str1;
  232.  
  233.     while (isspace(*p))    /* Find first target  */
  234.         p++;
  235.  
  236.     while (((q = index(p, '=')) != (char *) 0) &&
  237.            (p != q) && (q[-1] == '\\')) {    /* Find value */
  238.         register char  *a;
  239.  
  240.         a = q - 1;        /* Del \ chr; move rest back  */
  241.         p = q;
  242.         while (*a++ = *q++);
  243.     }
  244.  
  245.     if (q != (char *) 0) {
  246.         register char  *a;
  247.  
  248.         *q++ = '\0';    /* Separate name and val  */
  249.         while (isspace(*q))
  250.         q++;
  251.         if (p = rindex(q, '\n'))
  252.         *p = '\0';
  253.  
  254.         p = str1;
  255.         if ((a = gettok(&p)) == (char *) 0)
  256.         error("No macro name");
  257.  
  258.         setmacro(a, q);
  259.  
  260.         if (getline(str1, fd))
  261.         return;
  262.         continue;
  263.     }
  264.     expand(str1);
  265.     p = str1;
  266.  
  267.     while (((q = index(p, ':')) != (char *) 0) &&
  268.            (p != q) && (q[-1] == '\\')) {    /* Find dependents  */
  269.         register char  *a;
  270.  
  271.         a = q - 1;        /* Del \ chr; move rest back  */
  272.         p = q;
  273.         while (*a++ = *q++);
  274.     }
  275.  
  276.     if (q == (char *) 0)
  277.         error("No targets provided");
  278.  
  279.     *q++ = '\0';        /* Separate targets and dependents  */
  280.  
  281.     if (*q == ':') {    /* Double colon */
  282.         dbl = 1;
  283.         q++;
  284.     } else
  285.         dbl = 0;
  286.  
  287.     for (dp = (struct depend *) 0; ((p = gettok(&q)) != (char *) 0);)
  288.         /* get list of dep's */
  289.     {
  290.         np = newname(p);    /* Intern name  */
  291.         dp = newdep(np, dp);/* Add to dep list */
  292.     }
  293.  
  294.     *((q = str1) + strlen(str1) + 1) = '\0';
  295.     /* Need two nulls for gettok (Remember separation)  */
  296.  
  297.     cp = (struct cmd *) 0;
  298.     if (getline(str2, fd) == FALSE) {    /* Get commands  */
  299. #ifdef os9
  300.         while (*str2 == ' ')
  301. #else
  302.         while (*str2 == '\t')
  303. #endif
  304.         {
  305.         cp = newcmd(&str2[0], cp);
  306.         if (getline(str2, fd))
  307.             break;
  308.         }
  309.     }
  310.     while ((p = gettok(&q)) != (char *) 0) {    /* Get list of targ's */
  311.         np = newname(p);    /* Intern name  */
  312.         newline(np, dp, cp, dbl);
  313.         if (!firstname && p[0] != '.')
  314.         firstname = np;
  315.     }
  316.  
  317.     if (feof(fd))        /* EOF?  */
  318.         return;
  319.  
  320.     strcpy(str1, str2);
  321.     }
  322. }
  323.